home *** CD-ROM | disk | FTP | other *** search
/ Programming Microsoft Visual Basic .NET / Programming Microsoft Visual Basic .NET (Microsoft Press)(X08-78517)(2002).bin / 15 reflection / commandlineobjectbrowser / module1.vb < prev    next >
Text File  |  2002-03-16  |  10KB  |  263 lines

  1. Imports System.Reflection
  2.  
  3. Module MainModule
  4.  
  5.     Sub Main()
  6.         ' Get command-line arguments.
  7.         Dim args() As String = Environment.GetCommandLineArgs()
  8.         Dim cmd As String = Environment.CommandLine
  9.         Dim ty As Type
  10.         Dim mbrTypes As MemberTypes = MemberTypes.All
  11.         Dim mbrName As String = ""
  12.         Dim mi As MemberInfo
  13.  
  14.         ' If no arguments, /? or /help
  15.         If args.Length <= 1 OrElse args(1) = "/?" OrElse _
  16.             String.Compare(args(1), "/help", True) = 0 Then
  17.             ' Show command-line syntax and exit.
  18.             Console.WriteLine("Command-line Type Browser - by Francesco Balena")
  19.             Console.WriteLine("   Syntax:  typebrow typename [membername[*]]")
  20.             Exit Sub
  21.         End If
  22.  
  23.         Dim i As Integer = args(1).IndexOf(","c)
  24.         If i < 0 Then
  25.             ' Create the type as specified by first argument.
  26.             ty = Type.GetType(args(1), False, True)
  27.         Else
  28.             ' Create the assembly specified in the last part of the first argument
  29.             Dim asmname As String = args(1).Substring(i + 1)
  30.             Dim asm As [Assembly] = [Assembly].LoadWithPartialName(asmname)
  31.             ' Get the type in the specified assembly.
  32.             ty = asm.GetType(args(1).Substring(0, i), False, True)
  33.         End If
  34.  
  35.         If ty Is Nothing Then
  36.             ' Exit if error.
  37.             Console.WriteLine("Unable to create type ""{0}""", args(1))
  38.             Exit Sub
  39.         End If
  40.  
  41.         ' If the user asked for a particular name.
  42.         If args.Length > 2 Then
  43.             ' Retrieve the name
  44.             mbrName = args(2)
  45.         End If
  46.  
  47.         ' Get the list of member info to be displayed
  48.         Dim minfos() As MemberInfo = ty.FindMembers(mbrTypes, _
  49.             BindingFlags.Public Or BindingFlags.Instance Or _
  50.             BindingFlags.Static, _
  51.             AddressOf CustomMemberFilter, mbrName)
  52.  
  53.         ' Display information on all these members.
  54.         For Each mi In minfos
  55.             Console.WriteLine(MemberDescription(mi))
  56.         Next
  57.     End Sub
  58.  
  59.     ' This is the custom filter for members.
  60.     ' On entry filterCriteria holds the name of the member we're looking for.
  61.     ' (Supports partial names with a trailing asterisk, as in "Repl*".)
  62.  
  63.     Function CustomMemberFilter(ByVal m As MemberInfo, _
  64.         ByVal filterCriteria As Object) As Boolean
  65.         ' Discard accessor methods for properties.
  66.         If m.Name.StartsWith("get_") Or m.Name.StartsWith("set_") Then
  67.             Return False
  68.         End If
  69.  
  70.         ' Get the search filter in uppercase.
  71.         Dim search As String = filterCriteria.ToString.ToUpper
  72.         If search = "" Then Return True
  73.  
  74.         If search.EndsWith("*") Then
  75.             ' If there is a trailing asterisk, checks for partial match.
  76.             If m.Name.ToUpper.StartsWith(search.Substring(0, search.Length - 1)) _
  77.                 Then Return True
  78.         Else
  79.             ' Otherwise search for exact match.
  80.             If m.Name.ToUpper = search Then Return True
  81.         End If
  82.     End Function
  83.  
  84.     ' Return the syntax for a member (field, property, methods, event).
  85.     Function MemberDescription(ByVal mi As MemberInfo) As String
  86.         Dim res As String
  87.  
  88.         ' Different treatment for different types
  89.         Select Case mi.MemberType
  90.             Case MemberTypes.Field
  91.                 ' Fields: append As clause.
  92.                 Dim fdi As FieldInfo = CType(mi, FieldInfo)
  93.                 res &= NameDescription(mi, fdi.IsStatic) & _
  94.                     VBTypeDescription(fdi.FieldType)
  95.  
  96.             Case MemberTypes.Property
  97.                 ' Properties: append parameter list and return type.
  98.                 Dim pri As PropertyInfo = CType(mi, PropertyInfo)
  99.                 res &= NameDescription(mi, False) & _
  100.                     ParamListDescription(pri.GetIndexParameters)
  101.                 res &= VBTypeDescription(pri.PropertyType)
  102.  
  103.             Case MemberTypes.Method
  104.                 ' Methods: append parameter list and return type.
  105.                 Dim mti As MethodInfo = CType(mi, MethodInfo)
  106.                 res &= NameDescription(mi, mti.IsStatic) & _
  107.                     ParamListDescription(mti.GetParameters)
  108.                 If Not (mti.ReturnType Is Nothing) Then
  109.                     res &= VBTypeDescription(mti.ReturnType, True)
  110.                 End If
  111.  
  112.             Case MemberTypes.Constructor
  113.                 ' Constructor
  114.                 Dim cti As ConstructorInfo = CType(mi, ConstructorInfo)
  115.                 res &= NameDescription(mi, False) & _
  116.                     ParamListDescription(cti.GetParameters)
  117.  
  118.             Case MemberTypes.Event
  119.                 ' Events: append parameter list.
  120.                 Dim evi As EventInfo = CType(mi, EventInfo)
  121.                 ' Get the type that corresponds to the underlying delegate.
  122.                 Dim delType As Type = evi.EventHandlerType
  123.                 Dim mi2 As MethodInfo = delType.GetMethod("Invoke")
  124.                 res &= NameDescription(mi, False) & _
  125.                     ParamListDescription(mi2.GetParameters)
  126.         End Select
  127.  
  128.         Return res
  129.     End Function
  130.  
  131.     ' Return a description for name.
  132.     ' (Including Shared and member type description.)
  133.     Function NameDescription(ByVal mi As MemberInfo, ByVal IsStatic As Boolean) _
  134.         As String
  135.         Dim res As String
  136.  
  137.         ' Prefix with Shared if necessary
  138.         If IsStatic Then
  139.             res = "Shared "
  140.         End If
  141.  
  142.         ' Append member type, but distinguish between Sub and Function
  143.         If mi.MemberType <> MemberTypes.Method Then
  144.             ' if not a method, we can simply use the Enum.Format method.
  145.             res &= [Enum].Format(mi.MemberType.GetType, mi.MemberType, "G") & " "
  146.         Else
  147.             Dim meth As MethodInfo = CType(mi, MethodInfo)
  148.             If meth.ReturnType.Name = "Void" Then
  149.                 res &= "Sub "
  150.             Else
  151.                 res &= "Function "
  152.             End If
  153.         End If
  154.  
  155.  
  156.         ' Append name and return to caller.
  157.         If mi.MemberType = MemberTypes.Constructor Then
  158.             ' Visual Basic constructors are named "new"
  159.             res &= "New"
  160.         Else
  161.             ' A non-constructor element.
  162.             res &= mi.Name
  163.         End If
  164.  
  165.         Return res
  166.     End Function
  167.  
  168.     ' Return the description for a list of parameters.
  169.     Function ParamListDescription(ByVal pinfos() As ParameterInfo) As String
  170.         Dim res As String = "("
  171.         Dim i As Integer
  172.  
  173.         ' Iterate over all parameters.
  174.         For i = 0 To pinfos.GetUpperBound(0)
  175.             ' Append description for this parameter.
  176.             res &= ParamDescription(pinfos(i))
  177.             ' Append a comma if this isn't the last argument.
  178.             If i < pinfos.GetUpperBound(0) Then res &= ", "
  179.         Next
  180.         ' Close the parenthesis and return to caller.
  181.         Return res & ")"
  182.     End Function
  183.  
  184.     ' Return a description for a single parameter.
  185.     Function ParamDescription(ByVal pi As ParameterInfo) As String
  186.         Dim res As String
  187.         Dim pt As Type = pi.ParameterType
  188.  
  189.         ' Start with Optional if necessary.
  190.         If pi.IsOptional Then res = "Optional "
  191.  
  192.         ' Append ByVal or ByRef.
  193.         If pt.IsByRef Then
  194.             res &= "ByRef "
  195.         Else
  196.             res &= "ByVal "
  197.         End If
  198.  
  199.         ' Append the parameter name.
  200.         res &= pi.Name
  201.         ' Append the type, but convert it to VB syntax.
  202.         res &= VBTypeDescription(pt)
  203.  
  204.         ' Append the default value, if there is one.
  205.         If pi.IsOptional Then
  206.             ' Enclose the default value within quotes if it is a string.
  207.             If pt Is GetType(System.String) Then
  208.                 res &= " = """ & pi.DefaultValue.ToString & """"
  209.             Else
  210.                 res &= " = " & pi.DefaultValue.ToString
  211.             End If
  212.         End If
  213.  
  214.         ' Return to the caller.
  215.         Return res
  216.     End Function
  217.  
  218.     ' Return a parameter type in VB-friendly format.
  219.     Function VBTypeDescription(ByVal ty As Type, _
  220.         Optional ByVal PostfixArrayMarks As Boolean = False) As String
  221.         Dim res As String
  222.  
  223.         ' Get the return type as a string.
  224.         res &= ty.Name
  225.         ' Drop trailing "[]" pair, is there is one.
  226.         If res.EndsWith("[]") Then
  227.             res = res.Substring(0, res.Length - 2)
  228.         End If
  229.         ' Drop trailing *, if there is one.
  230.         If res.EndsWith("*") Then
  231.             res = res.Substring(0, res.Length - 1)
  232.         End If
  233.  
  234.         ' Adjust for VB-friendly names.
  235.         Select Case res
  236.             Case "Int16"
  237.                 res = "Short"
  238.             Case "Int32"
  239.                 res = "Integer"
  240.             Case "Int64"
  241.                 res = "Long"
  242.             Case "Void"
  243.                 ' this is the type "returned" by Sub
  244.                 Return ""
  245.         End Select
  246.  
  247.         ' Append "AS" and "()" if this is an array.
  248.         If Not ty.IsArray Then
  249.             res = " As " & res
  250.         ElseIf PostfixArrayMarks Then
  251.             ' Append trailing () pair.
  252.             res = " As " & res & "()"
  253.         Else
  254.             ' Prefix leading () pair.
  255.             res = "() As " & res
  256.         End If
  257.  
  258.         ' Return to the caller.
  259.         Return res
  260.     End Function
  261.  
  262. End Module
  263.